home *** CD-ROM | disk | FTP | other *** search
/ Programmers Heaven 2 / Programmers Heaven 2.iso / files / graphics / library / wgt51_r2.zip / WGT5 / EXAMPLES / WGT68 / WGT68D.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-03  |  8.5 KB  |  401 lines

  1. #include <wgt5.h>
  2. #include <math.h>
  3.  
  4. /*
  5. ==============================================================================
  6.               WordUp Graphics Toolkit Version 5.0
  7.                  Demonstration Program 68d
  8.  
  9.  Same as wgt68c.c, but uses timer controlled animation.
  10.  
  11.  *** PROJECT ***
  12.  This program requires the WGT5_WC.LIB file to be linked.
  13.  
  14.  *** DATA FILES ***
  15.  STREET.PAL, RUN.SPR
  16.                                WATCOM C++ VERSION
  17. ==============================================================================
  18. */
  19.  
  20. unsigned char shadowtable[256];    /* Shadow table */
  21. unsigned char *transparency_table; /* a 65536 byte table,
  22.                       allocated dynamically */
  23.  
  24. color pal[256];         /* The palette used for every graphic image */
  25. block sprites[200];     /* Array of images for the running robot */
  26.  
  27. block background;       /* Holds the background scrolling image */
  28. block work;             /* Page for constructing each frame */
  29. int oldmode;
  30.  
  31. int animation_count;    /* Used for animation timing */
  32. int movement_multiplier;/* Number of times to move objects, ground, etc */
  33.  
  34. /* A structure which holds the scrolling values for each horizontal line */
  35. typedef struct
  36.  {
  37.   int x;                /* Current x value, shifted by 8 */
  38.   int increment;        /* fixed point increment */
  39.  } line_scroll;
  40. line_scroll lines[80];  /* 80 scrolling lines along the ground */
  41.  
  42. /* A simple sprite structure */
  43. typedef struct
  44.  {
  45.   int x;
  46.   int y;
  47.   int anm;              /* Sprite number */
  48.  } sprite;
  49. sprite people[5];
  50.  
  51.  
  52. int backx = 0;          /* X value for the scrolling rocks */
  53. int backinc;            /* X increment for scrolling rocks */
  54.  
  55.  
  56.  
  57.  
  58. /* Loads the graphics files, and allocates buffers */
  59. void load_graphics (void)
  60. {
  61.  work = wallocblock (320, 200);
  62.  /* Allocate a work buffer */
  63.  
  64.  wloadsprites (pal, "run.spr", sprites, 0, 199);
  65.  background = wloadpak ("street.pak");
  66.  wsetpalette (0, 255, pal);
  67.  
  68.  transparency_table = (unsigned char *)malloc (65536);
  69. }
  70.  
  71.  
  72.  
  73. /* Frees the buffers and sprites */
  74. void free_graphics (void)
  75. {
  76.  free (transparency_table);
  77.  wfreesprites (sprites, 0, 199);
  78.  wfreeblock (background);
  79.  wfreeblock (work);
  80. }
  81.  
  82.  
  83. /* Set up the initial scrolling values */
  84. void init_lines (void)
  85. {
  86. int i;
  87. int inc;
  88.  
  89.  inc = 128;     /* slowest scrolling speed (128/256 of a pixel */
  90.  
  91.  backx = 0;     /* rocks x value */
  92.  backinc = inc; /* rocks same speed as the ground */
  93.  
  94.  for (i = 0; i < 80; i++)
  95.   {
  96.    lines[i].x = 0;              /* clear out the x value */
  97.    lines[i].increment = inc;    /* set the scroll speed */
  98.    inc += 32;                   /* Make the next row move faster */
  99.   }
  100.  
  101. }
  102.  
  103.  
  104.  
  105. /* Construct the background image */
  106. void animate_lines (void)
  107. {
  108. block source1, source2;
  109. block dest1, dest2;
  110. block origsource, origdest;
  111. int i;
  112. int x;
  113. int mult;
  114.  
  115.  wcopyscreen (0, 0, 319, 51, background, 0, 0, work);
  116.  /* Draw the moon stationary */
  117.  
  118.  /* Scroll the rocks */
  119.  for (mult = 0; mult <= movement_multiplier; mult++)
  120.    {
  121.     backx += backinc;
  122.     if (backx >= 81920)   /* 81920 is 320 << 8 */
  123.        backx -= 81920;
  124.    }
  125.  
  126.  x = backx >> 8;
  127.  
  128.  /* Copy the rocks */
  129.  wcopyscreen (x, 52, 319, 119, background, 0, 52, work);
  130.  if (x > 0)
  131.    wcopyscreen (0, 52, x-1, 119, background, 320 - x, 52, work);
  132.  
  133.  
  134.  origdest = abuf + 120 * 320;           /* First row to copy */
  135.  origsource = background + 120 * 320;   /* First row to copy */
  136.  
  137.  for (i = 0; i < 80; i++)
  138.   {
  139.    /* Scroll this line */
  140.    for (mult = 0; mult <= movement_multiplier; mult++)
  141.     {
  142.      lines[i].x += lines[i].increment;
  143.      if (lines[i].x >= 81920)   /* 81920 is 320 << 8, wraps scroll around */
  144.     lines[i].x -= 81920;
  145.     }
  146.    
  147.    x = lines[i].x >> 8;
  148.    /* Get the x coord */
  149.  
  150.    dest1 = origdest + i * 320;
  151.    dest2 = dest1 + (319 - x);
  152.    source1 = origsource + i * 320;
  153.    source2 = source1 + x;
  154.    
  155.    /* Copy the line in two steps */
  156.    memcpy (dest1, source2, 320 - x);
  157.    if (x > 0)
  158.     memcpy (dest2, source1, x + 1);
  159.    
  160.   }
  161.  
  162. }
  163.  
  164.  
  165.  
  166. /* Animates and displays the running man */
  167. void animate_man (void)
  168. {
  169. int mult;
  170.  
  171.  for (mult = 0; mult <= movement_multiplier; mult++)
  172.  {
  173.   people[0].anm++;
  174.   if (people[0].anm > 29)
  175.     people[0].anm = 0;
  176.  }
  177.  
  178.  wputblock_shade (people[0].x, 158, sprites[people[0].anm+30],
  179.         shadowtable, SHADE_SHADOW);
  180.  wputblock_shade (people[0].x, people[0].y, sprites[people[0].anm],
  181.         transparency_table, SHADE_TRANSLUCENT);
  182. }
  183.  
  184.  
  185.  
  186. void wcreate_shadow_table (color *palette)
  187. {
  188. float fr, fg, fb;
  189. long ir, ig, ib;
  190.  
  191. long absr, absg, absb;
  192.  
  193.  
  194. int r,g,b;
  195.  
  196. short col;
  197. short findcol;
  198.  
  199. unsigned long lowest;
  200. unsigned char bestfit;
  201. unsigned long coldif;
  202.  
  203.  for (col = 0; col < 256; col++)
  204.   {
  205.  
  206.    fr = (float)palette[col].r * (0.5);
  207.    fg = (float)palette[col].g * (0.5);
  208.    fb = (float)palette[col].b * (0.5);
  209.  
  210.    ir = fr;
  211.    ig = fg;
  212.    ib = fb;
  213.  
  214.    lowest = 655350;
  215.    for  (findcol = 0; findcol < 256; findcol++)
  216.     {
  217.       absr = abs ( (long)palette[findcol].r - ir);
  218.       absg = abs ( (long)palette[findcol].g - ig);
  219.       absb = abs ( (long)palette[findcol].b - ib);
  220.  
  221.       coldif = absr + absg + absb;
  222.       if  ((coldif < lowest) && (findcol != col))
  223.       {
  224.     lowest = coldif;
  225.     bestfit = findcol;
  226.       }
  227.     }
  228.    shadowtable[col] = bestfit;
  229.   }
  230.  
  231. }
  232.  
  233.  
  234. void wcreate_transparency_table (color *pal)
  235. {
  236. float lightlevel1;
  237. float lightlevel2;
  238. float fr, fg, fb;
  239. float fr2, fg2, fb2;
  240. long ir, ig, ib;
  241.  
  242. long absr, absg, absb;
  243.  
  244. short col, col2;
  245. short findcol;
  246.  
  247. unsigned long lowest;
  248. unsigned char bestfit;
  249. unsigned long coldif;
  250.  
  251.  
  252.  lightlevel1 = 0.5;     /* Percent of color 1 */
  253.  lightlevel2 = 0.5;     /* Percent of color 2 */
  254.  
  255.  /* Lightlevel1 and lightlevel2 must total to 1 */
  256.  
  257.  /* Transparency is created by taking two colors, multiplying the
  258.  RGB values by a percentage, and adding the RGB values together.  The
  259.  new color will contain a little bit of each oringal color. */
  260.  
  261.  
  262.  /* For each of the 256 colors, we can mix with any other color, therefore
  263.  we need a 256x256 table. */
  264.  
  265.  wtextcolor (15);
  266.  wtexttransparent (TEXTFGBG);
  267.  wgtprintf (0, 0, NULL, "Making transparency table...", col2);
  268.  
  269.  for (col2 = 0; col2 < 256; col2++)
  270.  {
  271.   for (col = 0; col < 256; col++)
  272.   {
  273.    fr = (float)pal[col].r * lightlevel1;
  274.    fg = (float)pal[col].g * lightlevel1;
  275.    fb = (float)pal[col].b * lightlevel1;
  276.  
  277.    fr2= (float)pal[col2].r * lightlevel2;
  278.    fg2= (float)pal[col2].g * lightlevel2;
  279.    fb2= (float)pal[col2].b * lightlevel2;
  280.  
  281.    ir = (fr + fr2);
  282.    ig = (fg + fg2);
  283.    ib = (fb + fb2);
  284.  
  285.    lowest = 655350;
  286.    for  (findcol = 0; findcol < 256; findcol++)
  287.     {
  288.       absr = abs ( (long)pal[findcol].r - ir) * 30;
  289.       absg = abs ( (long)pal[findcol].g - ig) * 59;
  290.       absb = abs ( (long)pal[findcol].b - ib) * 11;
  291.  
  292.       coldif = sqrt(absr*absr + absg*absg + absb*absb);
  293.       if  (coldif < lowest)
  294.       {
  295.     lowest = coldif;
  296.     bestfit = findcol;
  297.       }
  298.     }
  299.    transparency_table[col2 * 256L + col] = bestfit;
  300.   }
  301.  
  302.   wgtprintf (0, 8, NULL, "Color %03hi", col2);
  303.  }
  304.  
  305. }
  306.  
  307.  
  308. void animation_timer (void)
  309. {
  310.  animation_count++;
  311. }
  312.  
  313.  
  314.  
  315. int load_table (char *filename, block table, int size)
  316. {
  317. FILE *in;
  318.  
  319.  in = fopen (filename, "rb");
  320.  if (in == NULL)
  321.    return 0;
  322.  fread (table, size, 1, in);
  323.  fclose (in);
  324.  return 1;
  325. }
  326.  
  327.  
  328. void save_table (char *filename, block table, int size)
  329. {
  330. FILE *out;
  331.  
  332.  out = fopen (filename, "wb");
  333.  fwrite (table, size, 1, out);
  334.  fclose (out);
  335.  
  336. }
  337.  
  338.  
  339.  
  340. void main (void)
  341. {
  342.   oldmode = wgetmode ();
  343.   if (!vgadetected ())
  344.   {
  345.     printf ("VGA is required to run this program...");
  346.     exit (1);
  347.   }
  348.  
  349.   printf ("WGT Example #68d\n\n");
  350.   printf ("This example adds timer controlled animation.\n");
  351.   printf ("\nPress any key to begin.\n");
  352.   getch ();
  353.  
  354.   vga256 ();
  355.  
  356.  load_graphics ();
  357.  
  358.  init_lines ();
  359.  
  360.  /* Set the position of the running man */
  361.  people[0].x = 120;
  362.  people[0].y = 50;
  363.  people[0].anm = 0;
  364.  
  365.  wcreate_shadow_table (pal);
  366.  
  367.  if (!load_table ("trans.dat", transparency_table, 65536))
  368.   {
  369.    wcreate_transparency_table (pal);
  370.    save_table ("trans.dat", transparency_table, 65536); 
  371.   }
  372.  
  373.  
  374.  animation_count = 0;
  375.  winittimer ();
  376.  wstarttimer (animation_timer, TICKS (20));
  377.  
  378.  do {
  379.   wsetscreen (work);
  380.  
  381.   movement_multiplier = animation_count;
  382.   if (movement_multiplier > 0)
  383.    {
  384.     animation_count = 0;
  385.  
  386.     animate_lines ();
  387.     animate_man ();
  388.     wnormscreen ();
  389.  
  390.     wputblock (0, 0, work, 0);
  391.    }
  392.   } while (!kbhit ());
  393.  
  394.  wstoptimer ();
  395.  wdonetimer ();
  396.  
  397.  free_graphics ();
  398.  wsetmode (oldmode);
  399. }
  400.  
  401.